package slhs.tempo.TableAnalyzer;

/**
 * How filters are combined: 1. Each type of filter has it's own filter object, these objects are added on a compound
 * aray of filters and whenever a new filter is created/updated it is added/updated in the array. In order to keep
 * filters from piling up they are not added in a list or appended at the end of an array, they have been given a
 * permanent index. The indices are as follows: Subject Names Filter : 0 Non Experimental Items Filter: 1
 * 
 * */

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.DropMode;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;

import org.mlc.swing.layout.LayoutConstraintsManager;
import org.openswing.swing.client.GridControl;
import org.openswing.swing.util.client.ClientUtils;

import slhs.tempo.dataImporterUtilities.OutFileFields;
import slhs.tempo.pivotTableUtilities.DataConversionProgressBar;
import slhs.tempo.pivotTableUtilities.PivotTableWizard;
import slhs.tempo.scriptGenerator.PanelHandler;

import com.jgoodies.forms.factories.DefaultComponentFactory;

public class TablePanelHandler extends JPanel implements PanelHandler, KeyListener {

    private static final String TABLE_PANEL_LAYOUT_XML_FILE = "TABLE_PANEL_LAYOUT.XML";
    private static final int SUBJECT_FILTER_INDEX = 0;
    private static final int NON_EXP_ITEMS_FILTER_INDEX = 1;
    private static final int SIMPLE_TEXT_FILTER_INDEX = 2;
    private static final int INCORRECT_RESPONSE_FILTER_INDEX = 3;
    private static final int RESPONSE_UPPER_LIMIT_FILTER_INDEX = 4;
    private static final int RESPONSE_LOWER_LIMIT_FILTER_INDEX = 5;
    private static final int BUTTONS_PANEL_HEIGHT = 180;
    private static final int TABLE_LEFT_RIGHT_INSETS = 30;
    private static final int TABLE_HEIGHT_MARGIN = 80;
    private static final int NUMBER_OF_FILTERS = 6;
    private static final String SUBJECT_FILTER = "Subject Filter";
    private static final String NON_EXP_ITEMS_FILTER = "Non Exp Items Filter";
    public static String EXPERIMENTAL_PARAMETER_IDENTIFIER_STRING;

    private int screenWidth;
    private int screenHeight;
    private RowFilter<DefaultTableModel, Object> textFilter = null;
    private RowFilter<DefaultTableModel, Object> columnTextFilter = null;
    private RowFilter<DefaultTableModel, Object> incorrectResponseFilter = null;
    private RowFilter<DefaultTableModel, Object> responseTimeFilter = null;

    private final RowFilter<DefaultTableModel, Object>[] compoundFilterArray = new RowFilter[NUMBER_OF_FILTERS];
    private RowFilter<DefaultTableModel, Object> compoundRowFilter = null;

    private final Object[] tableColoumns;
    private HashMap<String, Integer> columnTextFilterMap;

    private JPanel buttonsPanel;
    private final JPanel tableBasePanel;
    private static JTabbedPane tableTabs;

    public JButton saveCurrentStateButton;
    private JButton deleteSelectedRowButton;
    private JButton deleteSelectedColumnButton;
    private JButton undoDeleteButton;
    private JButton createPivotTablesButton;

    private Component tableButtonsSeparator;

    private JButton backButton;
    private JButton nextButton;
    private JButton closeButton;
    private JButton addColumnButton;
    private JButton exportButton;
    private JCheckBox showFilterControlsBox;
    private JTable table;
    private DefaultTableModel dataModel;
    private final OutFileFields[] outFileFieldsArray;

    private JScrollPane tableScrollPane;

    private FilterControlsFrameHandler filterControlsPanel;
    private TableRowSorter<DefaultTableModel> rowSorter;

    private TableStateMemento dataVectorMemento;
    private TableStateMemento columnVectorMemento;

    private TableColumnAdjuster tca;
    private ConcreteTableModelListener tableModelUpdater;

    public TablePanelHandler(Object[] tableColoumns, OutFileFields[] outFileFieldsArray) {

	this.tableColoumns = tableColoumns;
	this.outFileFieldsArray = outFileFieldsArray;

	tableBasePanel = new JPanel();
	getScreenSize();
	initComponents();
	addComponents();
	SaveCurrentState.tableNameObjectHashmap.put(new Integer(0), table);
    }

    private void addComponents() {

	LayoutConstraintsManager layoutConstraintsManager = LayoutConstraintsManager.getLayoutConstraintsManager(this
		.getClass().getResourceAsStream(TABLE_PANEL_LAYOUT_XML_FILE));
	LayoutManager panelLayout = layoutConstraintsManager.createLayout("panel", this);
	tableBasePanel.setLayout(panelLayout);
	buttonsPanel.setBorder(com.jgoodies.forms.factories.Borders.DIALOG_BORDER);
	buttonsPanel.setLayout(layoutConstraintsManager.createLayout("buttonsPanel", buttonsPanel));

	tableBasePanel.add(tableTabs, "tableTabs");
	tableBasePanel.add(buttonsPanel, "buttonsPanel");

	tableScrollPane.setPreferredSize(new Dimension((screenWidth - TABLE_LEFT_RIGHT_INSETS), (screenHeight
		- BUTTONS_PANEL_HEIGHT - TABLE_HEIGHT_MARGIN)));
	tableScrollPane.setAlignmentY(CENTER_ALIGNMENT);

	tableTabs.addTab("Raw Data", tableScrollPane);

	buttonsPanel.add(createPivotTablesButton, "createPivotTableButton");
	buttonsPanel.add(deleteSelectedRowButton, "deleteSelectedRowButton");
	buttonsPanel.add(backButton, "backButton");
	buttonsPanel.add(undoDeleteButton, "undoDeleteButton");
	buttonsPanel.add(showFilterControlsBox, "showFilterControlsBox");
	buttonsPanel.add(exportButton, "exportButton");
	buttonsPanel.add(addColumnButton, "addColumnButton");
	buttonsPanel.add(closeButton, "closeButton");
	buttonsPanel.add(tableButtonsSeparator, "tableButtonsSeparator");
	buttonsPanel.add(saveCurrentStateButton, "saveCurrentStateButton");
	buttonsPanel.add(nextButton, "nextButton");
	buttonsPanel.add(deleteSelectedColumnButton, "deleteSelectedColumnButton");

	// add action listeners
	showFilterControlsBox.setSelected(true);
	showFilterControlsBox.addActionListener(this);
	exportButton.addActionListener(this);
	addColumnButton.addActionListener(this);
	closeButton.addActionListener(this);
	nextButton.addActionListener(this);
	backButton.addActionListener(this);
	createPivotTablesButton.addActionListener(this);
	deleteSelectedRowButton.addActionListener(this);
	undoDeleteButton.addActionListener(this);
	saveCurrentStateButton.addActionListener(new SaveCurrentState(this));
	deleteSelectedColumnButton.addActionListener(this);

	// populate filter indices for columnTextFilters
	columnTextFilterMap.put(SUBJECT_FILTER, new Integer(SUBJECT_FILTER_INDEX));
	columnTextFilterMap.put(NON_EXP_ITEMS_FILTER, new Integer(NON_EXP_ITEMS_FILTER_INDEX));

	// Arrange for column header renames by user
	JTableHeader columnHeader = table.getTableHeader();
	columnHeader.addMouseListener(new MouseClickListener(this));

	// Arrange for cell delete functionality
	table.addKeyListener(this);

	// Arrange for new column addition
	table.setAutoCreateColumnsFromModel(false);

	// Arrange for any changes in the table
	dataModel.addTableModelListener(tableModelUpdater);

	// Arrange for drag and drop functionality (incomplete)
	table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
	// table.setRowSorter(null);
	table.setDragEnabled(true);
	table.setDropMode(DropMode.ON_OR_INSERT);
	table.setTransferHandler(new CellsTransferHandler());
	table.setFillsViewportHeight(true);

    }

    private void initComponents() {

	columnTextFilterMap = new HashMap<String, Integer>();
	tableTabs = new JTabbedPane(JTabbedPane.BOTTOM);
	saveCurrentStateButton = new JButton("Save Current State");
	deleteSelectedColumnButton = new JButton("Delete Selected Column");
	deleteSelectedRowButton = new JButton("Delete Selected Rows");
	undoDeleteButton = new JButton("Undo Delete");
	new ImageIcon("src/Images/toolbar_pivot_table_icon.gif");
	new ImageIcon("src/Images/export_to_excel.gif");
	// createPivotTablesButton = new JButton(pivotTableIcon);
	createPivotTablesButton = new JButton("Pivot Wizard");
	// exportButton = new JButton(excelIcon);
	exportButton = new JButton("Export to Excel");
	backButton = new JButton("Back");
	nextButton = new JButton("Next");
	closeButton = new JButton("Close");
	addColumnButton = new JButton("Add column");
	showFilterControlsBox = new JCheckBox("Filter Controls");
	tableButtonsSeparator = DefaultComponentFactory.getInstance().createSeparator("", SwingConstants.LEFT);

	buttonsPanel = new JPanel();
	buttonsPanel.setPreferredSize(new Dimension(screenWidth, BUTTONS_PANEL_HEIGHT));

	dataModel = new DefaultTableModel();

	for (int coloumnCount = 0; coloumnCount < tableColoumns.length; coloumnCount++) {
	    dataModel.addColumn(tableColoumns[coloumnCount]);
	}

	/* Add data to table */
	for (int fileCount = 0; fileCount < outFileFieldsArray.length; fileCount++) {
	    OutFileFields outFileFields = outFileFieldsArray[fileCount];
	    ArrayList<Vector> row = outFileFields.getData();

	    int totalNumberOfRows = outFileFields.getNumberOfRows();
	    for (int rowCount = 0; rowCount < totalNumberOfRows; rowCount++) {
		try {
		    dataModel.addRow(row.get(rowCount));
		} catch (Exception e) {
		    e.printStackTrace();
		}

	    }

	}

	/* Create a table and set controls */
	table = new JTable(dataModel);
	table.setGridColor(Color.LIGHT_GRAY);
	table.setSelectionBackground(Color.YELLOW);
	table.setSelectionForeground(Color.BLACK);
	table.setCellSelectionEnabled(true);
	table.setColumnSelectionAllowed(true);
	table.setDragEnabled(true);
	table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
	tca = new TableColumnAdjuster(table);
	tca.adjustColumns();

	tableScrollPane = new JScrollPane(table);
	tableScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
	tableScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

	/* Create a filter controls frame */
	filterControlsPanel = new FilterControlsFrameHandler(this);
	filterControlsPanel.setVisible(true);

	/* Configure sorter and filter for table */
	rowSorter = new TableRowSorter<DefaultTableModel>(dataModel);
	table.setRowSorter(rowSorter);

	/* Initialize table memento */
	dataVectorMemento = new TableStateMemento();
	columnVectorMemento = new TableStateMemento();

	tableModelUpdater = new ConcreteTableModelListener(table);
    }

    protected void uncheckFiltersControlBox() {
	showFilterControlsBox.setSelected(false);
    }

    protected void checkFiltersControlBox() {
	showFilterControlsBox.setSelected(true);
    }

    public String[] getTableColumnsList() {
	int columnCount = dataModel.getColumnCount();
	String[] columnList = new String[columnCount];
	for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
	    String columnName = dataModel.getColumnName(columnIndex);
	    columnList[columnIndex] = columnName;
	}

	return columnList;
    }

    public String[] getSubjectList() {
	String[] columnList = this.getTableColumnsList();
	String[] subjectArray;
	int tableRowCount = dataModel.getRowCount();
	int columnIndex = 0;

	ArrayList<String> subjectList = new ArrayList<String>();
	try {
	    columnIndex = Arrays.asList(columnList).indexOf("Subject");
	    for (int rowIndex = 0; rowIndex < tableRowCount; rowIndex++) {
		String subjectName = (String) dataModel.getValueAt(rowIndex, columnIndex);
		if (subjectList.contains(subjectName) == false)
		    subjectList.add(subjectName);
	    }
	    Iterator subjectListIterator = subjectList.iterator();
	    subjectArray = new String[subjectList.size()];
	    int subjectListStartIndex = 0;
	    while (subjectListIterator.hasNext()) {
		subjectArray[subjectListStartIndex++] = (String) subjectListIterator.next();
	    }
	} catch (Exception e) {
	    subjectArray = null;
	    e.printStackTrace();
	}
	return subjectArray;
    }

    /**
     * Helper method to alloe deletion of selected row
     * */
    protected void removeSelectedRows() {
	// save table state
	Vector<?> dataVectorBeforeRowDeletion = dataModel.getDataVector();
	Vector columnDataVector = this.getColumnDataVector();
	dataVectorMemento.saveCurrentState(dataVectorBeforeRowDeletion);
	columnVectorMemento.saveCurrentState(columnDataVector);
	int[] selectedRowIndices = table.getSelectedRows();
	try {
	    while (selectedRowIndices.length != 0) {
		dataModel.removeRow(selectedRowIndices[0]);
		selectedRowIndices = table.getSelectedRows();
	    }

	} catch (Exception e) {
	    e.printStackTrace();
	}
    }

    /**
     * Helper method to allow deletion of selected columns
     * */
    protected void removeSelectedColumns() {
	DefaultTableModel newModel = (DefaultTableModel) ConcreteTableModelListener.getUpdatedModel();
	Vector dataVectorBeforeColumnDeletion = newModel.getDataVector();
	Vector columnDataVectorBefore = this.getColumnDataVector();
	dataVectorMemento.saveCurrentState(dataVectorBeforeColumnDeletion);
	columnVectorMemento.saveCurrentState(columnDataVectorBefore);

	int[] selectedColumnIndices = table.getSelectedColumns();
	try {
	    while (selectedColumnIndices.length != 0) {
		table.removeColumn(table.getColumnModel().getColumn(selectedColumnIndices[0]));
		selectedColumnIndices = table.getSelectedColumns();

	    }
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }

    /**
     * This method populates screenWidth and screenHeight variables.
     */
    private void getScreenSize() {
	GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
	GraphicsDevice[] gs = ge.getScreenDevices();

	// Get size of each screen
	for (int i = 0; i < gs.length; i++) {
	    DisplayMode dm = gs[i].getDisplayMode();
	    screenWidth = dm.getWidth();
	    screenHeight = dm.getHeight();
	}
    }

    /***************************************************************************
     * Table Row Filter - Start
     * *************************************************************************/
    public void columnTextFilter(String filterText, int columnIndex, int columnTextFilterNumber) {
	columnTextFilter = null;
	// If current expression doesn't parse, don't update.
	try {
	    columnTextFilter = RowFilter.regexFilter(filterText, columnIndex);
	} catch (java.util.regex.PatternSyntaxException e) {
	    return;
	}
	this.compoundFilterArray[columnTextFilterNumber] = columnTextFilter;
	applyCompoundFilter();
    }

    /***************************************************************************
     * Table Row Filter End
     * *************************************************************************/

    /***************************************************************************
     * Simple Text Filter - Start
     * *************************************************************************/
    protected void plainTextFilter(String filterRegExp) {
	textFilter = null;
	// If current expression doesn't parse, don't update.
	try {
	    textFilter = RowFilter.regexFilter(filterRegExp);
	} catch (java.util.regex.PatternSyntaxException e) {
	    return;
	}
	this.compoundFilterArray[SIMPLE_TEXT_FILTER_INDEX] = textFilter;
	applyCompoundFilter();
    }

    /***************************************************************************
     * Simple Text filter End
     * *************************************************************************/

    /***************************************************************************
     * Incorrect response Filter - Start
     * *************************************************************************/
    /**
     * @param: userAnswerColumnIndex : Index of column containing user responses
     * @param: expectedAnswerColumnIndex : Index of column containing expected responses
     * @return
     * */

    public void incorrectResponseFilter(final int userAnswerColumnIndex, final int expectedAnswerColumnIndex) {
	incorrectResponseFilter = new RowFilter<DefaultTableModel, Object>() {
	    @Override
	    public boolean include(Entry entry) {
		String actualResponse = entry.getStringValue(userAnswerColumnIndex);
		String expectedResponse = entry.getStringValue(expectedAnswerColumnIndex);
		return expectedResponse.contains(actualResponse);
	    }
	};

	// replace the filter with new object, each time the filter is updated
	this.compoundFilterArray[INCORRECT_RESPONSE_FILTER_INDEX] = incorrectResponseFilter;
	applyCompoundFilter();
    }

    /***************************************************************************
     * Incorrect response filter - End
     * *************************************************************************/

    /***************************************************************************
     * Response time filter - Start
     * *************************************************************************/
    /**
     * @param responseTimeColumnIndex
     *            : Index of column containing response times
     * @param limitTime
     *            : Upper/Lower limit on response time
     * @param discardAboveLimitTime
     *            : true if the values above limitTime are to be filtered out and false if the values below limitTime
     *            are to be discarded
     * @return
     * */
    public void rectionTimeFilter(final int responseTimeColumnIndex, final int limitTime,
	    final boolean discardAboveLimitTime) {
	responseTimeFilter = new RowFilter<DefaultTableModel, Object>() {
	    @Override
	    public boolean include(Entry entry) {
		int actualResponseTime = Integer.valueOf(entry.getStringValue(responseTimeColumnIndex)).intValue();
		return (discardAboveLimitTime) ? (actualResponseTime < limitTime) : (actualResponseTime > limitTime);
	    }
	};

	// replace the filter with new object, each time the filter is updated
	if (discardAboveLimitTime)
	    this.compoundFilterArray[RESPONSE_UPPER_LIMIT_FILTER_INDEX] = responseTimeFilter;
	else
	    this.compoundFilterArray[RESPONSE_LOWER_LIMIT_FILTER_INDEX] = responseTimeFilter;

	applyCompoundFilter();
    }

    /***************************************************************************
     * Response time filter - End
     * *************************************************************************/

    /**
     * Helper method to update and apply filters
     * */
    private void applyCompoundFilter() {
	ArrayList<RowFilter<DefaultTableModel, Object>> compoundFilterList = new ArrayList<RowFilter<DefaultTableModel, Object>>();
	for (int i = 0; i < compoundFilterArray.length; i++) {
	    if (compoundFilterArray[i] != null) {
		compoundFilterList.add(compoundFilterArray[i]);
	    }
	}
	// System.out.println("Applying " + compoundFilterList.size() + " filters");
	compoundRowFilter = RowFilter.andFilter(compoundFilterList);
	rowSorter.setRowFilter(compoundRowFilter);
	dataModel.fireTableDataChanged();
    }

    @Override
    public JPanel getPanel() {
	return tableBasePanel;
    }

    public Vector getColumnDataVector() {
	Vector<String> columnDataVector = new Vector();
	int columnCount = table.getColumnCount();
	for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
	    columnDataVector.add(table.getColumnName(columnIndex));

	}
	return columnDataVector;
    }

    /***************************************************************************
     * Action Listeners - Start
     * *************************************************************************/

    @Override
    public void actionPerformed(ActionEvent ae) {
	Object source = ae.getSource();
	// filter controls box action
	if (source.equals(showFilterControlsBox)) {
	    if (showFilterControlsBox.isSelected() == false) {
		filterControlsPanel.dispose();
	    } else
		filterControlsPanel.setVisible(true);
	}

	// close button action
	if (source.equals(closeButton)) {
	    System.exit(0);
	}

	// add columns button action
	if (source.equals(addColumnButton)) {
	    String columnName = JOptionPane.showInputDialog("Enter the name for new column");
	    if (columnName != null)
		addNewColumn(table, columnName, null);
	}

	// delete selected row button
	if (source.equals(this.deleteSelectedRowButton)) {
	    this.removeSelectedRows();
	}

	// delete selected columns button
	if (source.equals(this.deleteSelectedColumnButton)) {
	    this.removeSelectedColumns();
	}

	// undo delete button
	if (source.equals(this.undoDeleteButton)) {
	    this.undoDelete();
	}

	// create pivot table button
	if (source.equals(this.createPivotTablesButton)) {

	    final JFrame frame = new JFrame("Data Conversion in Progress");
	    ClientUtils.centerFrame(frame);
	    frame.setSize(400, 200);
	    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	    // Create and set up the content pane.
	    JComponent newContentPane = new DataConversionProgressBar();
	    newContentPane.setOpaque(true); // content panes must be opaque
	    frame.setContentPane(newContentPane);

	    // Display the window.
	    frame.pack();
	    frame.setVisible(true);

	    final TablePanelHandler currentObject = this;
	    createPivotTablesButton.setEnabled(false);
	    createPivotTablesButton.removeActionListener(this);

	    SwingWorker worker = new SwingWorker<Void, Void>() {
		@Override
		protected Void doInBackground() throws Exception {
		    createPivotTablesButton.setText("Wait");
		    new PivotTableWizard(currentObject);
		    return null;
		}

		@Override
		public void done() {
		    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		    createPivotTablesButton.setEnabled(true);
		    createPivotTablesButton.addActionListener(currentObject);
		    createPivotTablesButton.setText("Pivot Wizard");
		    frame.setVisible(false);
		    frame.dispose();

		}

	    };

	    worker.execute();
	}

	// export to excel button
	if (source.equals(this.exportButton)) {
	    int selectedTabIndex = this.tableTabs.getSelectedIndex();
	    JTable table = SaveCurrentState.tableNameObjectHashmap.get(new Integer(selectedTabIndex));
	    System.out.println(table.getModel().getRowCount());
	    GridControl grid = new GridControl();
	    grid.setController(null);
	}

    }

    /***************************************************************************
     * Action Listeners - End
     * *************************************************************************/

    /**
     * @param
     * @return
     * */
    protected void undoDelete() {
	if (!dataVectorMemento.isEmpty() && !columnVectorMemento.isEmpty()) {
	    table.setAutoCreateColumnsFromModel(true);
	    Vector dataVectorBeforeDelete = (Vector) dataVectorMemento.getLastState();
	    Vector columnIdentifiersBeforeDelete = (Vector) columnVectorMemento.getLastState();
	    if ((dataVectorBeforeDelete != null) && (columnIdentifiersBeforeDelete != null)) {
		dataModel.setDataVector(dataVectorBeforeDelete, columnIdentifiersBeforeDelete);
		tca.adjustColumns();
	    }
	    table.setAutoCreateColumnsFromModel(false);

	}

    }

    /**
     * @param columnName
     *            : Name of the column whose index is to be determined
     * @return index of column
     * */
    public int getColumnIndexByName2(String columnName) {
	int modelIndex = 0;
	try {
	    TableColumn column = table.getColumn(columnName);
	    modelIndex = column.getModelIndex();
	} catch (Exception e) {
	    /**
	     * will get into this section if the cell corresponding to exp item is empty
	     * */
	    e.printStackTrace();
	}
	return modelIndex;
    }

    /**
     * @param searchValue
     *            : String value of cell for which the column name is required
     * @return String value of column header (or simply column name)
     **/
    public String getColumnNameByItemName(String searchValue) {
	for (int rowIndex = 0; rowIndex < table.getRowCount(); rowIndex++) {
	    for (int columnIndex = 0; columnIndex < table.getColumnCount(); columnIndex++) {
		try {
		    String currentValue = table.getValueAt(rowIndex, columnIndex).toString();
		    if ((currentValue != null) && (currentValue != "") && (currentValue.equalsIgnoreCase(searchValue))) {
			EXPERIMENTAL_PARAMETER_IDENTIFIER_STRING = currentValue;
			return table.getColumnName(columnIndex);
		    }
		} catch (NullPointerException e) {
		    // e.printStackTrace();
		}

	    }
	}
	return null;
    }

    public int getColumnTextFilterIndex(String filterName) {
	Integer value = this.columnTextFilterMap.get(filterName);
	int filterIndex = value.intValue();
	return filterIndex;
    }

    /**
     * @param newTabName
     *            : Name for the new tab
     * @param newComponent
     *            : Component that needs to be added on the tab (can be a simple table, pivot table etc)
     */
    public void addNewTab(String newTabName, Component newComponent) {
	tableTabs.addTab(newTabName, newComponent);
	tableTabs.setSelectedIndex(tableTabs.getTabCount() - 1);

    }

    /**
     * @return table : current table object
     */
    public JTable getTable() {
	return table;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
     */
    @Override
    public void keyPressed(KeyEvent keyPressedEvent) {
	int keyCode = keyPressedEvent.getKeyCode();
	if ((keyCode == KeyEvent.VK_DELETE) || (keyCode == KeyEvent.VK_BACK_SPACE)) {
	    int[] selectedRows = table.getSelectedRows();
	    int[] selectedColumns = table.getSelectedColumns();
	    for (int rowIndex = 0; rowIndex < selectedRows.length; rowIndex++) {
		for (int columnIndex = 0; columnIndex < selectedColumns.length; columnIndex++) {
		    table.setValueAt(null, selectedRows[rowIndex], selectedColumns[columnIndex]);
		}
	    }
	}
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
     */
    @Override
    public void keyReleased(KeyEvent arg0) {

    }

    /*
     * (non-Javadoc)
     * 
     * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
     */
    @Override
    public void keyTyped(KeyEvent keyTypedEvent) {

    }

    public void addNewColumn(JTable table, Object headerLabel, Object[] values) {
	DefaultTableModel model = (DefaultTableModel) table.getModel();
	TableColumn col = new TableColumn(model.getColumnCount());

	// Ensure that auto-create is off
	if (table.getAutoCreateColumnsFromModel()) {
	    throw new IllegalStateException();
	}
	col.setHeaderValue(headerLabel);
	table.addColumn(col);
	model.addColumn(headerLabel.toString(), values);
    }

    /**
     * @return An array of Strings containing the names of the tables
     */
    public static String[] getTabsList() {
	int tabCount = tableTabs.getTabCount();
	String[] tabListArray = new String[tabCount];
	for (int tabIndex = 0; tabIndex < tabCount; tabIndex++) {
	    tabListArray[tabIndex] = tableTabs.getTitleAt(tabIndex);
	}
	return tabListArray;
    }

    /**
     * @return
     */
    public int getSelectedTabIndex() {
	// TODO Auto-generated method stub
	return tableTabs.getSelectedIndex();
    }

    /**
     * @param tabId
     * @return
     */
    public static JTable getTableOnTab(String tabId) {
	int returnTabIndex = -1;
	String[] tabsList = getTabsList();
	for (int tabIndex = 0; tabIndex < tabsList.length; tabIndex++) {
	    if (tabId.equals(tabsList[tabIndex]))
		returnTabIndex = tabIndex;
	}
	return SaveCurrentState.tableNameObjectHashmap.get(new Integer(returnTabIndex));
    }

}
